home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / turbo20.bqg / turbo20.bug
Text File  |  1985-03-15  |  7KB  |  152 lines

  1.                     ***** BUG REPORT *****
  2.          ***** MAJOR BUG IN TURBO PASCAL V2.00 *****
  3.                          July 1,1984
  4.  
  5. **************NOTE:  THIS BUG WAS FIXED PRIOR TO THE RELEASE
  6. **************OF 2.00B--PROBABLY DUE TO THE LABORIOUS EFFORT
  7. **************OF THE CONTRIBUTOR OF THIS BUG REPORT, WHO WAS
  8. **************ANONYMOUS IN THE FILE IN WHICH I FOUND IT.
  9. **************EVERYTHING EXCEPT THIS NOTE IS THE WORK OF THAT
  10. **************UNKNOWN BENEFACTOR, WHOEVER S/HE MAY BE.
  11. **************MY ONLY REASON FOR ADDING TO THIS FILE IS TO
  12. **************SAVE OTHERS THE CONCERN I HAD ABOUT MY COMPILER,
  13. **************AND SPARE THEM THE EFFORT OF INVESTIGATING A
  14. **************CORRECTED VERSION.  I DON'T KNOW ABOUT VERSIONS
  15. **************BETWEEN V2.00 AND V2.00B.
  16. **************                         Karl Brendel
  17.  
  18.  
  19.      The runtime routines  do  not  handle  a  floating-point 
  20. (real)  subtraction  correctly.  For  some subtractions,  the 
  21. correct  difference  is  returned;  for  others,  a  zero  is 
  22. returned. The following program demonstrates the bug:
  23.  
  24. program test;
  25. begin
  26.      writeln(9.+(-6.0));        { Wrong value returned }
  27.      writeln(-1.0+(-1.0));      { Correct value returned }
  28.      writeln(1-2);              { Correct value returned }
  29.      writeln(1.-2:10:2);        { Wrong value returned }
  30.      writeln(1.-2.0);           { Wrong value returned }
  31.      writeln(1-2.0);            { Wrong value returned }
  32.      writeln(456 - 123.0);      { Correct value returned }
  33. end.
  34.  
  35. A value of zero is returned on those lines marked as 'wrong'. 
  36. The other lines return the correct difference.
  37.  
  38.  
  39. THE CAUSE
  40.  
  41.     After disassembling and tracing through a sample compiled 
  42. program, the error was located in the following code:
  43.  
  44. XXXX:12FA E84FFF        CALL    124C            ; Subtract
  45. XXXX:12FD 7306          JNB     1305
  46. XXXX:12FF 80F780        XOR     BH,80           ; Handle negative
  47. XXXX:1302 E863FF        CALL    1268            ;   numbers
  48. XXXX:1305 8B4504        MOV     AX,[DI+04]      ; Is mantissa zero?
  49. XXXX:1308 0B4502        OR      AX,[DI+02]
  50. XXXX:130B 0A4501        OR      AL,[DI+01]      ; ***** ERROR *****
  51. XXXX:130E 740D          JZ      131D            ; Yes
  52. XXXX:1310 F6450580      TEST    BYTE PTR [DI+05],80  ; Normalize
  53. XXXX:1314 750C          JNZ     1322
  54.  
  55. (Comments  have  been  added for clarity).  This disassembled 
  56. code is located in the  routines  that  handle  addition  and 
  57. subtraction  (only the subtraction part is shown).  The error 
  58. occurs when the routine tests to see if  the  result  of  the 
  59. subtraction is zero. It tests for a zero by "OR-ing" together 
  60. the five bytes of the mantissa (the instructions that do this 
  61. are at offsets 1305H to 130BH). If the mantissa is zero, then 
  62. the result of this "multiple-or" will set the zero flag.  The 
  63. first  of  these instructions is a move of the word at [DI+4] 
  64. to AX.  The next instruction takes the logical OR of  AX  and 
  65. [DI+2].  No problem so far.  However, the last instruction is 
  66. "OR AL,[DI+1]",  an instruction that operates on a  byte  and 
  67. not  on  a word.  If the OR of the words at [DI+4] and [DI+2] 
  68. results in a word whose UPPER byte is NONZERO but whose LOWER 
  69. byte is ZERO,  then the next instruction, the "byte-wise" OR, 
  70. will SET the zero flag if the byte at [DI+1] is zero.  Notice 
  71. that the instruction at 130BH totally ignores the contents of 
  72. the upper byte of AX;  the flags are  set  according  to  the 
  73. lower byte of AX only.  This is what causes the error.
  74.  
  75.  
  76. THE FIX
  77.  
  78.      The fix to this bug is simple: simply exchange the order 
  79. of the two "OR" instructions.  This way, the zero flag is set 
  80. according  to  a  full  16-bit  OR  and  not  an  8-bit  one. 
  81. IMPORTANT:  Only persons familiar with the operation of DEBUG 
  82. should  attempt  the  following.  Using DEBUG,  the following 
  83. sequence of commands can be used to fix the bug:
  84.  
  85.      Assumptions and notes in the following:
  86.           1) ONLY WORK ON A COPY OF TURBO!  DO  NOT  USE 
  87.              YOUR MASTER COPY!
  88.           2) The sequence of commands shown below writes 
  89.              out  the   fixed   version   to   the  file 
  90.              'turbo.com'
  91.           3) Make sure that you have version 2.00
  92.           4) 'turbo.com'   must   be   in   the  current 
  93.              directory on drive B.
  94.           5) DOS  2.00  or  above  is  being  used  (the 
  95.              debugger in DOS 1.00 and 1.10 does not have 
  96.              the 'assemble' command).                           
  97.           6) Be  sure  to  verify  that  the code in the 
  98.              compiler is the same as  that  shown  below 
  99.              initially.  After the changes are made,  be 
  100.              sure to verify that the changes  have  been 
  101.              made  correctly  before  writing  the fixed 
  102.              version out to disk.
  103.  
  104. B>debug turbo.com
  105. -u 12fa             <- Verify the following locations
  106. XXXX:12FA E84FFF        CALL    124C
  107. XXXX:12FD 7306          JNB     1305
  108. XXXX:12FF 80F780        XOR     BH,80
  109. XXXX:1302 E863FF        CALL    1268
  110. XXXX:1305 8B4504        MOV     AX,[DI+04]
  111. XXXX:1308 0B4502        OR      AX,[DI+02]
  112. XXXX:130B 0A4501        OR      AL,[DI+01]
  113. XXXX:130E 740D          JZ      131D
  114. XXXX:1310 F6450580      TEST    BYTE PTR [DI+05],80
  115. XXXX:1314 750C          JNZ     1322
  116. XXXX:1316 E8F9FE        CALL    1212
  117. XXXX:1319 FE0D          DEC     BYTE PTR [DI]
  118. -a 1308             <- Make changes
  119. XXXX:1308 or al,[di+1]
  120. XXXX:130E or ax,[di+2]
  121. XXXX:1311                       <- Press 'enter'
  122. -u 12fa             <- Verify that the changes are correct
  123. XXXX:12FA E84FFF        CALL    124C
  124. XXXX:12FD 7306          JNB     1305
  125. XXXX:12FF 80F780        XOR     BH,80
  126. XXXX:1302 E863FF        CALL    1268
  127. XXXX:1305 8B4504        MOV     AX,[DI+04]
  128. XXXX:1308 0A4501        OR      AL,[DI+01]
  129. XXXX:130B 0B4502        OR      AX,[DI+02]
  130. XXXX:130E 740D          JZ      131D
  131. XXXX:1310 F6450580      TEST    BYTE PTR [DI+05],80
  132. XXXX:1314 750C          JNZ     1322
  133. XXXX:1316 E8F9FE        CALL    1212
  134. XXXX:1319 FE0D          DEC     BYTE PTR [DI]
  135. -w                  <- Save fixed version of turbo
  136. Writing 8E80 bytes
  137. -q
  138.  
  139. B>
  140.  
  141. <end of fix>
  142.  
  143.  
  144. OTHER NOTES ABOUT TURBO
  145.  
  146.      One  cannot  set  breakpoints  in TURBO using DEBUG.  It 
  147. seems that TURBO  uses  the  breakpoint  interrupt  for  some 
  148. hideous  reason.  If  one  attempts  to set breakpoints,  the 
  149. system will probably crash.  Tracing,  however,  does seem to 
  150. work.  The  above  bug  was  tracked down only after hours of 
  151. tracing (by maching and by hand) and disassembling.
  152.